package ssh

import (
	"fmt"
	"strconv"
)

type Metric struct {
	Type string `json:"type" xml:"type"`
	Name string `json:"name" xml:"name"`
}

var (
	STATUS_METRIC_VMLCK    Metric = Metric{"status", "VmLck"}
	STATUS_METRIC_VMPIN    Metric = Metric{"status", "VmPin"}
	STATUS_METRIC_VMHWM    Metric = Metric{"status", "VmHWM"}
	STATUS_METRIC_VMRSS    Metric = Metric{"status", "VmRSS"}
	STATUS_METRIC_VMSTK    Metric = Metric{"status", "VmStk"}
	STATUS_METRIC_VMEXE    Metric = Metric{"status", "VmExe"}
	STATUS_METRIC_VMLIB    Metric = Metric{"status", "VmLib"}
	STATUS_METRIC_VMPTE    Metric = Metric{"status", "VmPTE"}
	STATUS_METRIC_VMPEAK   Metric = Metric{"status", "VmPeak"}
	STATUS_METRIC_VMSIZE   Metric = Metric{"status", "VmSize"}
	STATUS_METRIC_VMDATA   Metric = Metric{"status", "VmData"}
	STATUS_METRIC_VMSWAP   Metric = Metric{"status", "VmSwap"}
	STATUS_METRIC_RSSANON  Metric = Metric{"status", "RssAnon"}
	STATUS_METRIC_RSSFILE  Metric = Metric{"status", "RssFile"}
	STATUS_METRIC_RSSSHMEM Metric = Metric{"status", "RssShmem"}

	SMAPS_METRIC_RSS              Metric = Metric{"smaps", "Rss"}
	SMAPS_METRIC_PSS              Metric = Metric{"smaps", "Pss"}
	SMAPS_METRIC_SIZE             Metric = Metric{"smaps", "Size"}
	SMAPS_METRIC_SWAP             Metric = Metric{"smaps", "Swap"}
	SMAPS_METRIC_LOCKED           Metric = Metric{"smaps", "Locked"}
	SMAPS_METRIC_SWAP_PSS         Metric = Metric{"smaps", "SwapPss"}
	SMAPS_METRIC_LAZY_FREE        Metric = Metric{"smaps", "LazyFree"}
	SMAPS_METRIC_ANONYMOUS        Metric = Metric{"smaps", "Anonymous"}
	SMAPS_METRIC_REFERENCED       Metric = Metric{"smaps", "Referenced"}
	SMAPS_METRIC_MMU_PAGESIZE     Metric = Metric{"smaps", "MMUPageSize"}
	SMAPS_METRIC_SHARED_DIRTY     Metric = Metric{"smaps", "Shared_Dirty"}
	SMAPS_METRIC_SHARED_CLEAN     Metric = Metric{"smaps", "Shared_Clean"}
	SMAPS_METRIC_SHARED_HUGETLB   Metric = Metric{"smaps", "Shared_Hugetlb"}
	SMAPS_METRIC_ANON_HUGE_PAGES  Metric = Metric{"smaps", "AnonHugePages"}
	SMAPS_METRIC_FILE_PMD_MAPPED  Metric = Metric{"smaps", "FilePmdMapped"}
	SMAPS_METRIC_SHMEM_PMD_MAPPED Metric = Metric{"smaps", "ShmemPmdMapped"}
	SMAPS_METRIC_KERNELP_PAGESIZE Metric = Metric{"smaps", "KernelPageSize"}
	SMAPS_METRIC_PRIVATE_HUGETLB  Metric = Metric{"smaps", "Private_Hugetlb"}
)

// GrepProcMetric 通过指定进程ID，查询/proc/{pid}/{type}中对应的指标参数，并对其进行求和
//
// 指标参数格式：至少2个字段（2列），且第2个字段为数值类型
func (own *Client) GrepProcMetric(pid int64, metric Metric) (float64, error) {
	// grep '^Pss' /proc/1040/smaps | awk '{total += $2}; END {print total}'
	res, err := own.Execute(fmt.Sprintf("grep '^%s' /proc/%d/%s | awk '{total += $2}; END {print total}'", metric.Name, pid, metric.Type))
	if err != nil {
		return 0, err
	}

	nums := numberRegexp.FindAllString(res, -1)
	if len(nums) == 0 {
		return 0, nil
	}

	return strconv.ParseFloat(nums[0], 64)
}
